<?php
/**
 * Copyright (c) 2020
 * 摘    要：
 * 作    者：san
 * 修改日期：2020.04.01
 */

namespace App\Service;

use App\Model\Role;
use App\Model\User;
use App\Model\WorkSpace;
use App\Model\WorkSpaceUser;
use App\Library\Clog\Log;
use ErrorException;
use Exception;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Model;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Context;

class WorkSpaceService extends BaseService
{
    /**
     * WorkSpaceService constructor.
     */
    public function __construct()
    {
        parent::__construct();

        $this->redis = redis();
    }

    /**
     * 部门列表
     */
    public function query()
    {
        $uid = Context::get('user')->user_id;

        if ($uid == User::ADMIN_UID) {
            $workspace = WorkSpace::query()
                ->orderBy('id', 'desc')
                ->get();
        } else {

            $records = Db::table('workspace_user')
                ->where('user_id', '=', $uid)
                ->where(function ($query) {
                    $query->where('role_id', '=', Role::ROLE_OWNER)
                        ->orWhere('role_id', '=', Role::ROLE_MASTER);
                })
                ->orderBy('id', 'desc')
                ->get('workspace_id')
                ->toArray();

            $ids = [];
            if ($records) {
                foreach ($records as $value) {
                    $ids[] = $value->workspace_id;
                }
            }
            $workspace = WorkSpace::query()
                ->whereIn('id', $ids)
                ->orderBy('id', 'desc')->get();
        }

        $result = [];

        foreach ($workspace as $key => $value) {
            $result[$key]['id']   = $value['id'];
            $result[$key]['name'] = $value['name'];

            $roleA = Db::table('workspace_user as a')
                ->select(['a.user_id', 'b.nick_name as name', 'b.email'])
                ->leftJoin('users as b', 'b.user_id', '=', 'a.user_id')
                ->where('a.workspace_id', $value['id'])->where('a.role_id', 2)->first();

            $result[$key]['owner']       = $roleA ? $roleA->name : '无';
            $result[$key]['owner_id']    = $roleA ? $roleA->user_id : 0;
            $result[$key]['owner_email'] = $roleA ? $roleA->email : '无';

            $roleB = Db::table('workspace_user as a')
                ->select(['a.user_id', 'b.nick_name as name', 'b.email'])
                ->leftJoin('users as b', 'b.user_id', '=', 'a.user_id')
                ->where('a.workspace_id', $value['id'])->where('a.role_id', 3)->first();

            $result[$key]['master']       = $roleB ? $roleB->name : '无';
            $result[$key]['master_id']    = $roleB ? $roleB->user_id : 0;
            $result[$key]['master_email'] = $roleA ? $roleB->email : '无';
        }
        return $result;
    }

    /**
     * 新增部门
     *
     * @param $data
     * @throws ErrorException
     */
    public function add($data)
    {
        $name     = $data['name'];
        $ownerId  = $data['owner'];
        $masterId = $data['master'];

        if ($ownerId == $masterId) throw new ErrorException(t('message.12049'));

        Db::beginTransaction();
        try {
            // 1、校验name是否存在
            $hasOne = WorkSpace::query()->where('name', $name)->first();
            if ($hasOne) throw new ErrorException(t('message.12050'));

            // 2、校验人是否存在
            $hasUser = User::query()->where('user_id', $ownerId)->first();
            if (!$hasUser) throw new ErrorException(t('message.12051'));

            $hasUser = User::query()->where('user_id', $masterId)->first();
            if (!$hasUser) throw new ErrorException(t('message.12052'));

            // 3、部门录入
            $id = Workspace::query()->insertGetId(['name' => $name]);
            if (!$id) throw new ErrorException(t('message.12002'));

            // 4、部门用户信息录入
            $res = WorkSpaceUser::query()->insert([
                ['user_id' => $ownerId, 'workspace_id' => $id, 'role_id' => Role::ROLE_OWNER],
                ['user_id' => $masterId, 'workspace_id' => $id, 'role_id' => Role::ROLE_MASTER],
            ]);
            if (!$res) throw new ErrorException(t('message.12002'));
            Db::commit();
        } catch (Exception $exception) {
            Db::rollBack();
            throw new \ErrorException($exception->getMessage());
        }
    }

    /**
     * 更新部门
     *
     * @param $data
     * @throws ErrorException
     */
    public function edit($data)
    {
        $id       = $data['id'];
        $name     = $data['name'];
        $ownerId  = $data['owner'];
        $masterId = $data['master'];

        if ($ownerId == $masterId) throw new ErrorException(t('message.12049'));

        $workspace = $this->_checkExists($id);

        Db::beginTransaction();
        try {
            // 1、更新部门
            if ($name != $workspace->name) {
                $workspace->name = $name;
                $res             = $workspace->save();
                if (!$res) throw new \ErrorException(t('message.12002'));
            }
            // 2、删除原部门所属信息
            WorkSpaceUser::query()->where(['role_id' => Role::ROLE_OWNER, 'workspace_id' => $id])->delete();
            WorkSpaceUser::query()->where(['role_id' => Role::ROLE_MASTER, 'workspace_id' => $id])->delete();
            User::findFromCache($ownerId)->removeRole(Role::ROLE_OWNER);
            User::findFromCache($masterId)->removeRole(Role::ROLE_MASTER);

            // 3、插入新部门所属信息
            $res1 = $this->addUser([
                'user_id'      => $ownerId,
                'workspace_id' => $id,
                'role_id'      => Role::ROLE_OWNER,
            ]);
            $res2 = $this->addUser([
                'user_id'      => $masterId,
                'workspace_id' => $id,
                'role_id'      => Role::ROLE_MASTER,
            ]);
            if (!($res1 && $res2)) throw new ErrorException(t('message.12002'));
            Db::commit();
        } catch (Exception $exception) {
            Db::rollBack();
            Log::exception($exception);
            throw new \ErrorException($exception->getMessage());
        }
    }

    /**
     * 删除部门
     *
     * @param $id
     * @throws ErrorException
     */
    public function delete($id)
    {
        $workspace = $this->_checkExists($id);

        Db::beginTransaction();
        try {
            // 1、删除部门
            $res = $workspace->delete();
            if (!$res) throw new \ErrorException(t('message.12002'));
            // 2、删除部门下面的所有成员
            WorkSpaceUser::query()->where('workspace_id', '=', $id)->delete();
            Db::commit();
        } catch (Exception $exception) {
            Db::rollBack();
            throw new \ErrorException($exception->getMessage());
        }
    }

    /**
     * 部门用户新增
     *
     * @param $data
     * @throws ErrorException
     * @return mixed
     */
    public function addUser($data)
    {
        $hasOne = WorkSpaceUser::query()->where($data)->first();
        if ($hasOne) throw new ErrorException(t('message.12055'));

        $hasOne = Db::table('workspace_user')
            ->where([
                'workspace_id' => $data['workspace_id'],
                'user_id'      => $data['user_id'],
            ])->first();

        if ($hasOne) {
            $role = Role::query()->find($hasOne->role_id);
            $user = User::query()->find($data['user_id']);
            throw new ErrorException("【{$user->nick_name}】在此部门已配置【{$role->name}】角色");
        }

        if (in_array($data['role_id'], [Role::ROLE_OWNER, Role::ROLE_MASTER])) {
            $hasOne = Db::table('workspace_user')
                ->Where([
                    'workspace_id' => $data['workspace_id'],
                    'role_id'      => $data['role_id'],
                ])->first();

            if ($hasOne) {
                $message = ($data['role_id'] == Role::ROLE_OWNER) ? '该部门已有管理员' : '该部门已有审核人';
                throw new ErrorException($message);
            }
        }

        //用户赋予角色
        User::findFromCache($data['user_id'])->assignRole((int)$data['role_id']);

        return WorkSpaceUser::create($data);
    }

    /**
     * 查询部门用户
     *
     * @param int $page
     * @param int $pageSize
     * @param array $condition
     * @return array
     */
    public function queryUser($page = 1, $pageSize = 10, $condition = [])
    {
        $fields = [
            'a.id',
            'a.role_id',
            'a.user_id',
            'a.workspace_id',
            'b.nick_name',
            'b.avatar',
            'b.email',
            'c.name',
            'd.name as role_name'
        ];

        $uid = Context::get('user')->user_id;

        $query = Db::table('workspace_user as a')
            ->select($fields)
            ->leftJoin('users as b', 'b.user_id', '=', 'a.user_id')
            ->leftJoin('workspace as c', 'c.id', '=', 'a.workspace_id')
            ->leftJoin('roles as d', 'd.id', '=', 'a.role_id')
            ->whereNull('b.deleted_at');

        if ($uid != Role::ROLE_ADMIN) {
            $ids     = [];
            $records = Db::table('workspace_user')
                ->where('user_id', '=', $uid)
                ->where(function ($query) {
                    $query->where('role_id', '=', Role::ROLE_OWNER)
                        ->orWhere('role_id', '=', Role::ROLE_MASTER);
                })
                ->orderBy('id', 'desc')
                ->get('workspace_id')
                ->toArray();
            if ($records) {
                foreach ($records as $value) {
                    $ids[] = $value->workspace_id;
                }
            }
            $query = $query->whereIn('c.id', $ids);
        }

        if ($condition) {
            $query = $query->where($condition);
        }

        $count  = $query->count();
        $result = $query->limit($pageSize)->offset(($page - 1) * $pageSize)
            ->orderBy('c.id', 'desc')
            ->orderBy('d.id', 'asc')
            ->get();

        return [
            'list'  => $result,
            'total' => $count,
        ];
    }

    /**
     * 删除用户
     *
     * @param $id
     * @throws ErrorException
     * @throws Exception
     * @return bool
     */
    public function deleteUser($id)
    {
        $detail = $this->_checkUserExists($id);

        $res = $detail->delete();
        if (!$res) {
            throw new \ErrorException(t('message.12002'));
        }

        return true;
    }


    /**
     * 检测记录是否存在
     *
     * @param $id
     * @throws ErrorException
     * @return Builder|Builder[]|Collection|Model|null
     */
    private function _checkExists($id)
    {
        $workspace = WorkSpace::query()->find($id);

        if (!$workspace) {
            throw new \ErrorException(t('message.12053'));
        }

        return $workspace;
    }

    /**
     * 检测记录是否存在
     *
     * @param $id
     * @throws ErrorException
     * @return Builder|Builder[]|Collection|Model|null
     */
    private function _checkUserExists($id)
    {
        $workspaceUser = WorkSpaceUser::query()->find($id);

        if (!$workspaceUser) {
            throw new \ErrorException(t('message.12054'));
        }

        return $workspaceUser;
    }
}
